package gestorvideoclub;


import gestorvideoclub.enumeraciones.*;
import gestorvideoclub.jdbc.*;
import gestorvideoclub.util.*;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import javax.management.timer.Timer;
import java.util.*;
import java.util.ArrayList;

public class Alquiler {
    //private Ubicacion ubicacion;
    private int idAlquiler;
    private Producto producto;
    //private int idProducto;
    private Cliente cliente;
    //private int idCliente;
    private Tarifa tarifa;
    //private int idTarifa;
    private Date fechaInicio;
    private Date fechaPrevistaDev;
    private Date fechaDevolucionReal;
    private static double margen;

    public Alquiler(){}


    //En el constructor inicializao fecha de devoluci�n final porque cuando se crea el objeto alquiler ser� vac�o
    public Alquiler(Producto producto, Cliente cliente, Tarifa tarifa, Date fechaPrevistaDev){
        //this.ubicacion = ubicacion;
        this.producto = producto;
        this.cliente = cliente;
        this.tarifa = tarifa;
        this.fechaInicio = new Date();
        this.fechaPrevistaDev = fechaPrevistaDev;
    }

    static{
        margen = 1.0;
    }

    public int getIdAlquiler() {
        return idAlquiler;
    }

    public void setIdAlquiler(int idAlquiler) {
        this.idAlquiler = idAlquiler;
    }

    public Cliente getCliente() {
        return cliente;
    }

    public void setCliente(Cliente cliente) {
        this.cliente = cliente;
    }

    public Date getFechaDevolucionReal() {
        return fechaDevolucionReal;
    }

    public void setFechaDevolucionReal(Date fechaDevolucionReal) {
        this.fechaDevolucionReal = fechaDevolucionReal;
    }

    public Date getFechaInicio() {
        return fechaInicio;
    }

    public void setFechaInicio(Date fechaInicio) {
        this.fechaInicio = fechaInicio;
    }

    public Date getFechaPrevistaDev() {
        return fechaPrevistaDev;
    }

    public void setFechaPrevistaDev(Date fechaPrevistaDev) {
        this.fechaPrevistaDev = fechaPrevistaDev;
    }

    public static double getMargen() {
        return margen;
    }

    public static void setMargen(double margen) {
        Alquiler.margen = margen;
    }

    public Producto getProducto() {
        return producto;
    }

    public void setProducto(Producto Producto) {
        this.producto = Producto;
    }

    public Tarifa getTarifa() {
        return tarifa;
    }

    public void setTarifa(Tarifa tarifa) {
        this.tarifa = tarifa;
    }

    /*
    public Ubicacion getUbicacion() {
        return ubicacion;
    }

    public void setUbicacion(Ubicacion ubicacion) {
        this.ubicacion = ubicacion;
    }
     * */
    

    @Override
    public String toString()
    {
        String cad = this.getProducto().getTitulo();
        cad += " en formato "+this.getProducto().getTipo();
        cad += " Alquilada desde "+UtilFecha.fechaMostrar(this.getFechaInicio());
        cad += " hasta "+UtilFecha.fechaMostrar(this.fechaPrevistaDev);
       
        return cad;
    }

    @Override
    public boolean equals(Object o)
    {
        if(o instanceof Alquiler)
        {
            Alquiler a = (Alquiler)o;
            if(this.getCliente().getId() == a.getCliente().getId() && this.getProducto().getId() == a.getProducto().getId()
               && this.getTarifa().getId() == a.getTarifa().getId() &&
               this.fechaInicio.equals(a.fechaInicio) && this.fechaPrevistaDev.equals(a.fechaPrevistaDev) && this.fechaDevolucionReal.equals(a.fechaPrevistaDev))
            {
                return true;
            }
        }
        return false;
    }

    @Override
    public int hashCode()
    {
        return 1;
    }

    
    //Aqui es donde quedará registrado el producto que se alquila con el cliente
    public void altaAlquiler(Cliente cliente, Producto producto)
    {
        if(cliente.getNumProdAlqActual()< Cliente.getNumMaxProducto()){
            if(producto.getEstado().equals(ProductoEnum.Disponible)){
                    if(cliente.getSaldo() > 0){
                            System.out.print("¿Cuántos días desea alquilar el producto?   ");
                            int dia = introduceDatos.introduceEntero();

        

                            double cargoAlquiler = dia * producto.getTarifa().getPrecio();
                            double saldoDisponible = cliente.getSaldo() - cargoAlquiler;

                            if(saldoDisponible + Alquiler.getMargen() >= 0){


                                        this.setCliente(cliente);
                                        this.setProducto(producto);
                                       
                                        this.setTarifa(this.getProducto().getTarifa());
                                        this.setFechaInicio(new Date());
                                        String fPrevista = UtilFecha.sumarDiasFecha(new Date(), dia);
                                        this.setFechaPrevistaDev(UtilFecha.obtenerFecha(fPrevista));
                                        boolean correcto = false;
                                        do{
                                            System.out.println("¿Está seguro de que quiere realizar el alquiler?");
                                            System.out.println("[1] Sí");
                                            System.out.println("[2] No");
                                            int opcion = introduceDatos.introduceEntero();
                                            switch(opcion){
                                                case 1:
                                                    AlquilerJDBC.insertarAlquiler(this);
                                                    System.out.println(this);
                                                    this.getProducto().getUbicacion().setColumna(-1);
                                                    this.getProducto().getUbicacion().setFila(-1);
                                                    producto.setEstado(ProductoEnum.Alquilado);
                                                    ProductoJDBC.modificarProducto(producto);

                                                    cliente.setSaldo(saldoDisponible);
                                                    cliente.setNumProdAlqActual(cliente.getNumProdAlqActual() + 1);
                                                    ClienteJDBC.modificarCliente(cliente);
                                                    correcto = true;
                                                    break;
                                                case 2:
                                                    System.out.println("El alquiler se ha cancelado");
                                                    this.getProducto().setEstado(ProductoEnum.Disponible);
                                                    ProductoJDBC.modificarProducto(producto);
                                                    correcto = true;
                                                    break;
                                                default:
                                                    System.out.println("Opción incorrecta");
                                           }
                                        }while(!correcto);
                            }
                            else{
                                System.out.println("No tiene saldo suficiente para realizar el alquiler");
                            }
                    }else{
                        System.out.println("\nNo tiene saldo para realizar un alquiler");
                    }
            }else{
                System.out.println("Este producto no está disponible para alquilar\n");
                //Reserva.altaReserva(cliente, producto);
            }
        }
        else{
            System.out.println("No puede realizar mas alquileres, actualmente tiene alquilado el numero maximo de producto");
        }
    }

    //consultar los datos referentes a un Alquiler
    public void consultaAlquiler()
    {
        System.out.println(this);
    }

    /**
     * Este metodo comprobara si el producto que se ha devuelto se ha hecho en la fecha estimada o
     * si lo entrega mas tarde. Este método es llamado en devoluciónAlquiler
     * @return devuelve true si lo entrega mas tarde o false en caso contrario
     */
    public boolean hayDemora()
    {
        //Accede al base de datos para traer todos los datos del alquiler
        boolean hay = false;
        Date fPrevista = this.getFechaPrevistaDev();
        Date fReal = this.getFechaDevolucionReal();

        if(fPrevista.compareTo(fReal)<0)
        {
            hay = true;
        }
        return hay;
    }


    /**
     * Este m�todo hace la operacion de devolucion del producto
     * @param producto que esta siendo devuelto
     */
    public static void devolucionAlquiler(Producto producto)
    {   int id = ProductoJDBC.obtenerTipoProductoPorId(producto);

        if(id != -1){
            producto.setId(id);
                Alquiler alquiler = AlquilerJDBC.obtenerUltimoAlquilerProducto(producto);
                if(alquiler!= null){
                    Cliente cliente = ClienteJDBC.obtenerClientePorId(alquiler.getCliente().getId());
                    alquiler.setFechaDevolucionReal(new Date());
                    AlquilerJDBC.modificarAlquiler(alquiler);
                    if(alquiler.hayDemora()){
                        alquiler.recargoPorDemora(cliente);
                    }
                    else{
                        System.out.println("La devolucion se ha realizado correctamente");
                    }
                        cliente.setNumProdAlqActual(cliente.getNumProdAlqActual()-1);
                        ClienteJDBC.modificarCliente(cliente);
                        producto.getUbicacion().setColumna(-1);
                        producto.getUbicacion().setFila(-1);
                        ProductoJDBC.modificarProducto(producto);
                    Reserva.comprobarReserva(producto);
                }
                else{
                    System.out.println("No existe producto entregado");
                }
        }
        else{
            System.out.println("El código del producto entregado no es correcto o no existe");
        }
    }



//\\\\\\\\\\\\a�adir a tarifa tituloProducto\\\\\\\\\\\\\\\\\
    public void compruebaTarifa(Producto producto)

    {

    }

    /**
     * Este método le da la posibilidad al usuario de alquilar el producto que ha reservado
     * @param reserva
     */
    public void alquilarProductoReservado(Reserva reserva)
    {
        //Cliente cliente = ClienteJDBC.obtenerClientePorId(reserva.getIdCliente());
        TipoProductoEnum tipo = reserva.getTipoProducto();
        boolean correcto = false;
        Producto producto = null;

        if(tipo.equals(TipoProductoEnum.DVD) || tipo.equals(TipoProductoEnum.BlueRay)){
            producto = PeliculaJDBC.obtenerPeliculaPorId(reserva.getProducto().getId());

        }else if(tipo.equals(TipoProductoEnum.Videojuego)){
                producto = VideojuegoJDBC.obtenerVideojuegoPorId(reserva.getProducto().getId());

        }
        producto.setId(reserva.getProducto().getId());
        do{
            System.out.println("¿Desea alquilar?");
            System.out.println("[1] Sí");
            System.out.println("[2] No");
            System.out.print("Seleccione la opción correspondiente: ");
            int opcion = introduceDatos.introduceEntero();
            switch(opcion){
                case 1:
                    producto.setEstado(ProductoEnum.Disponible);
                    this.altaAlquiler(reserva.getCliente(), producto);
                    reserva.setFechaAlquiler(new Date());
                    if(this.getFechaInicio() != null){
                        ReservaJDBC.modificarReserva(reserva);
                    }
                    correcto = true;
                    break;
                case 2:
                    System.out.println("No alquilará el producto");
                    reserva.setPendiente(false);
                    //El producto se pondrá disponible otra vez si no hay ninguna reserva más
                    Reserva.comprobarReserva(reserva.getProducto());
                    ReservaJDBC.modificarReserva(reserva);
                                       
                    correcto = true;
                    break;
                default:
                    System.out.println("Opción incorrecta");
            }
        }while(!correcto);
    }

    
    public void recargoPorDemora(Cliente cliente){
        
        Tarifa tarifa = TarifaJDBC.consultaTarifaPorId(this.getTarifa().getId());
        int diasRetraso = UtilFecha.calculaDiferenciaFecha(this.getFechaDevolucionReal(), this.getFechaPrevistaDev());
        System.out.println("Se ha retrasado "+diasRetraso+" día/s");
        double recargo = tarifa.getPrecio()*diasRetraso;
        System.out.println("Se le hará un recargo de "+recargo+" euros");
        cliente.retirarSaldo(recargo);
    }

    public static void productosAlquilado(){
        ArrayList<Alquiler> lista = AlquilerJDBC.consultarProductosAlquilados();
        if(!lista.isEmpty()){
            System.out.println(">>>>> PRODUCTOS ALQUILADOS ACTUALMENTE <<<<<\n");
            Iterator it = lista.iterator();
            while(it.hasNext()){
                Alquiler alquiler = (Alquiler)it.next();
                String cadena = "CÓDIGO: "+alquiler.getProducto().getCodigo()+" TÍTULO: "+alquiler.getProducto().getTitulo();
                cadena += " FECHA ALQUILER: "+UtilFecha.fechaMostrar(alquiler.getFechaInicio())+" FECHA PREVISTA DEVOLUCIÓN: "+UtilFecha.fechaMostrar(alquiler.getFechaPrevistaDev());
                cadena += " CLIENTE(dni): "+alquiler.getCliente().getDNI();
                System.out.println(cadena);
                System.out.println("-------------------------------------------------------------------------------------------------------------------");
            }
        }
        else{
            System.out.println("Actualmente no tiene productos alquilados");
        }
    }

}
